/**
 * @author jerry wu
 * @author Jiangcun ChiLie
 * Homework 1 for CS 149 - Summer 2013
 */

import java.util.Collections;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Stack;

public class Simulation {
	public static void main(String args[]) {
		float[] FCFSATT = new float[5], FCFSAWT = new float[5], FCFSART = new float[5];
		float[] SJFATT = new float[5], SJFAWT = new float[5], SJFART = new float[5];
		float[] SRTATT = new float[5], SRTAWT = new float[5], SRTART = new float[5];
		float[] RRATT = new float[5], RRAWT = new float[5], RRART = new float[5];
		float[] NHPFATT = new float[5], NHPFAWT = new float[5], NHPFART = new float[5];
		float[] PHPFATT = new float[5], PHPFAWT = new float[5], PHPFART = new float[5];
		for (int i = 0; i < 5; i++) {
			FCFSATT[i] = -1;
			FCFSAWT[i] = -1;
			FCFSART[i] = -1;
			SJFATT[i] = -1;
			SJFAWT[i] = -1;
			SJFART[i] = -1;
			SRTATT[i] = -1;
			SRTAWT[i] = -1;
			SRTART[i] = -1;
			RRATT[i] = -1;
			RRAWT[i] = -1;
			RRART[i] = -1;
			NHPFATT[i] = -1;
			NHPFAWT[i] = -1;
			NHPFART[i] = -1;
			PHPFATT[i] = -1;
			PHPFAWT[i] = -1;
			PHPFART[i] = -1;
		}
		
		for (int i = 0; i < 5; i++) {
			System.out.println("\nFCFS simulation");
			System.out.println("Simulation Time: " + (i + 1));
			int[] fcfsResult = FCFS();
			FCFSATT[i] = getATT1(fcfsResult);
			FCFSAWT[i] = getAWT1(fcfsResult);
			FCFSART[i] = getAWT1(fcfsResult);
			System.out.println("\nAverage Turn Around Time: " + FCFSATT[i]);
			System.out.println("Average Waiting Time: " + + FCFSAWT[i]);
			System.out.println("Average Response Time: " + FCFSART[i] +"\n");
			
			System.out.println("\nSJF simulation");
			System.out.println("Simulation Time: " + (i + 1));
			int[] sjfResult = SJF();
			SJFATT[i] = getATT1(sjfResult);
			SJFAWT[i] = getAWT1(sjfResult);
			SJFART[i] = getAWT1(sjfResult);
			System.out.println("\nAverage Turn Around Time: " + SJFATT[i]);
			System.out.println("Average Waiting Time: " + SJFAWT[i]);
			System.out.println("Average Response Time: " + SJFART[i] + "\n");
			
			System.out.println("\nSRT simulation");
			System.out.println("Simulation Time: " + (i + 1));
			int[] srtResult = SRT();
			SRTATT[i] = getATT2(srtResult);
			SRTAWT[i] = getAWT2(srtResult);
			SRTART[i] = getART2(srtResult);
			System.out.println("\nAverage Turn Around Time: " + SRTATT[i]);
			System.out.println("Average Waiting Time: " + SRTAWT[i]);
			System.out.println("Average Response Time: " + SRTART[i] + "\n");
			
			System.out.println("\nRR simulation");
			System.out.println("Simulation Time: " + (i + 1));
			int[] rrResult = RR();
			RRATT[i] = getATT2(rrResult);
			RRAWT[i] = getAWT2(rrResult);
			RRART[i] = getART2(rrResult);
			System.out.println("\nAverage Turn Around Time: " + RRATT[i]);
			System.out.println("Average Waiting Time: " + RRAWT[i]);
			System.out.println("Average Response Time: " + RRART[i] + "\n");
			
			System.out.println("\nNPHPF simulation");
			System.out.println("Simulation Time: " + (i + 1));
			int[] nhpfResult = NHPF();
			NHPFATT[i] = getATT1(nhpfResult);
			NHPFAWT[i] = getAWT1(nhpfResult);
			NHPFART[i] = getAWT1(nhpfResult);
			System.out.println("\nAverage Turn Around Time: " + NHPFATT[i]);
			System.out.println("Average Waiting Time: " + NHPFAWT[i]);
			System.out.println("Average Response Time: " + NHPFART[i] + "\n");
			
			System.out.println("\nPHPF simulation");
			System.out.println("Simulation Time: " + (i + 1));
			int[] phpfResult = PHPF();
			PHPFATT[i] = getATT2(phpfResult);
			PHPFAWT[i] = getAWT2(phpfResult);
			PHPFART[i] = getART2(phpfResult);
			System.out.println("\nAverage Turn Around Time: " + PHPFATT[i]);
			System.out.println("Average Waiting Time: " + PHPFAWT[i]);
			System.out.println("Average Response Time: " + PHPFART[i] + "\n");
		}		
		
		System.out.println("Final Statistics Result: ");
		System.out.println("\nFirst Come First Served Report");
		System.out.println("Average Turn Around Time: "+ getAverage(FCFSATT));
		System.out.println("Average Waiting Time: "+ getAverage(FCFSAWT));
		System.out.println("Average Response Time: "+ getAverage(FCFSART));
		
		System.out.println("\nShortest Job First Report");
		System.out.println("Average Turn Around Time: "+ getAverage(SJFATT));
		System.out.println("Average Waiting Time: "+ getAverage(SJFAWT));
		System.out.println("Average Response Time: "+ getAverage(SJFART));
		
		System.out.println("\nShortest Remaining Time Report");
		System.out.println("Average Turn Around Time: "+ getAverage(SRTATT));
		System.out.println("Average Waiting Time: "+ getAverage(SRTAWT));
		System.out.println("Average Response Time: "+ getAverage(SRTART));
		
		System.out.println("\nRound Robin Report");
		System.out.println("Average Turn Around Time: "+ getAverage(RRATT));
		System.out.println("Average Waiting Time: "+ getAverage(RRAWT));
		System.out.println("Average Response Time: "+ getAverage(RRART));
		
		System.out.println("\nNon-Preemptive Highest Priority First Report");
		System.out.println("Average Turn Around Time: "+ getAverage(NHPFATT));
		System.out.println("Average Waiting Time: "+ getAverage(NHPFAWT));
		System.out.println("Average Response Time: "+ getAverage(NHPFART));
		
		System.out.println("\nPreemptive Highest Priority First Report");
		System.out.println("Average Turn Around Time: "+ getAverage(PHPFATT));
		System.out.println("Average Waiting Time: "+ getAverage(PHPFAWT));
		System.out.println("Average Response Time: "+ getAverage(PHPFART));
	}

	
	/**
	 * Simulates the FCFS algorithm
	 * @author Jerry Wu
	 * @return array describes time table of the simulation
	 */
	protected static int[] FCFS() {
		List<HashMap<String, Number>> processLists = processGenerator();
		printList(processLists);
		HashMap<String, Number> currentProcess = null;
		int[] result = new int[102];
		
		for (int timeCount = 0; timeCount <= 100; timeCount++) {
			for (int i = 0; i < processLists.size(); i++) {
				if (processLists.get(i).get("arrivalTime").floatValue() <= timeCount && processLists.get(i).get("completed").floatValue() == 0) {
					if (currentProcess == null) {
						currentProcess = processLists.get(i);
					} 
				}
			}
			int currentCompleted = currentProcess.get("completed").intValue();
			currentCompleted++;
			currentProcess.put("completed", currentCompleted);
			for (int i = 0; i < processLists.size(); i++) {
				if (processLists.get(i).get("pid").equals(currentProcess.get("pid"))) {
					processLists.set(i, currentProcess);
				}
			}
			
			System.out.print(timeCount + "\t");
			System.out.print("pid: " + currentProcess.get("pid") + "\t");
			result[timeCount] = currentProcess.get("pid").intValue();
			System.out.println();
			
			
			if (currentProcess.get("runTime").equals(currentProcess.get("completed"))) {
				currentProcess = null;
			}
			
		}
		result[101] = processLists.size();
		return result;
	}
	
	/**
	 * Simulates the SJF algorithm
	 * @author Jerry Wu
	 * @return array describes time table of the simulation
	 */
	protected static int[] SJF() {
		List<HashMap<String, Number>> processLists = processGenerator();
		printList(processLists);
		List<Integer> runTimeList = new ArrayList<Integer>();
		HashMap<String, Number> currentProcess = null;
		int[] result = new int[102];
		
		for (int i = 0; i < processLists.size(); i++) {
			runTimeList.add(processLists.get(i).get("runTime").intValue());
		}
		Collections.sort(runTimeList);
		List<HashMap<String, Number>> sortedProcessList = new ArrayList<HashMap<String, Number>>();
		
		while (runTimeList.size() > 0) {
			int rTime = runTimeList.get(0);
			for (int i = 0; i < processLists.size(); i++) {
				if (processLists.get(i).get("runTime").intValue() == rTime) {
					sortedProcessList.add(processLists.get(i));
					processLists.remove(i);
					break;
				}
			}
			runTimeList.remove(0);
		}
		processLists = sortedProcessList;
		

		for (int timeCount = 0; timeCount <= 100; timeCount++) {
			for (int i = 0; i< processLists.size(); i++) {
				if (currentProcess == null && processLists.get(i).get("completed").floatValue() == 0) {
					currentProcess = processLists.get(i); 
				}
			}
			int currentCompleted = currentProcess.get("completed").intValue();
			currentCompleted++;
			currentProcess.put("completed", currentCompleted);
			
			System.out.print(timeCount + "\t");
			System.out.print("pid: " + currentProcess.get("pid") + "\t");
			result[timeCount] = currentProcess.get("pid").intValue();
			System.out.println();
			
			
			if (currentProcess.get("runTime").equals(currentProcess.get("completed"))) {
				currentProcess = null;
			}
		}
		result[101] = processLists.size();
		return result;
		
	}
	
	/**
	 * Simulates the Short Remaining Time Algorithm
	 * @author Jerry Wu
	 * @return array describes time table of the simulation
	 */
	protected static int[] SRT() {
		List<HashMap<String, Number>> processList = processGenerator();
		printList(processList);
		Stack<HashMap<String, Number>> suspendStack = new Stack<HashMap<String, Number>>();
		HashMap<String, Number> currentProcess = null;
		int[] result = new int[102];
		
		for (int timeCount = 0; timeCount <= 100; timeCount++) {
			for (int i = 0; i < processList.size(); i++) {
				if (processList.get(i).get("arrivalTime").floatValue() <= timeCount && processList.get(i).get("completed").intValue() == 0) {
					if (currentProcess == null) {
						if (!(suspendStack.empty())) {
							currentProcess = suspendStack.pop();
							HashMap<String, Number> nextProcess = processList.get(i);
							float currentTurnAroundTime = (float) currentProcess.get("arrivalTime").floatValue() + currentProcess.get("runTime").floatValue();
							float nextTurnAroundTime = (float) nextProcess.get("arrivalTime").floatValue() + nextProcess.get("runTime").floatValue();
							if (currentTurnAroundTime > nextTurnAroundTime) {
								suspendStack.push(currentProcess);
								currentProcess = nextProcess;
							}
						} else {
							currentProcess = processList.get(i);
						}
					} else {
						HashMap<String, Number> nextProcess = processList.get(i);
						float currentTurnAroundTime = (float) currentProcess.get("arrivalTime").floatValue() + currentProcess.get("runTime").floatValue();
						float nextTurnAroundTime = (float) nextProcess.get("arrivalTime").floatValue() + nextProcess.get("runTime").floatValue();
						if (currentTurnAroundTime > nextTurnAroundTime) {
							suspendStack.push(currentProcess);
							currentProcess = nextProcess;
						}
					}
					break;
				}
				
				if (currentProcess == null) {
					if (!(suspendStack.empty())) {
						currentProcess = suspendStack.pop();
						break;
					}
				}
			}
			int currentCompleted = currentProcess.get("completed").intValue();
			currentCompleted++;
			currentProcess.put("completed", currentCompleted);
			for (int i = 0; i < processList.size(); i++) {
				if (processList.get(i).get("pid").equals(currentProcess.get("pid"))) {
					processList.set(i, currentProcess);
				}
			}
			
			System.out.print(timeCount + "\t");
			System.out.print("pid: " + currentProcess.get("pid") + "\t");
			result[timeCount] = currentProcess.get("pid").intValue();
			System.out.println();
			
			
			if (currentProcess.get("runTime").equals(currentProcess.get("completed"))) {
				currentProcess = null;
			}
		}
		result[101] = processList.size();
		return result;
		
	}
	
	/**
	 * Simulates the Round Robin Algorithm within 100 time slices
	 * @autohr jerry wu
	 * @return array describes time table of the algorithm
	 */
	public static int[] RR() {
		List<HashMap<String, Number>> processList = processGenerator();
		printList(processList);
		HashMap<String, Number> currentProcess = null;
		int index = 0;
		int[] result = new int[102];
		
		for (int timeCount = 0; timeCount <= 100; timeCount++) {
			int pIndex = index % processList.size();
			currentProcess = processList.get(pIndex);
			while (currentProcess.get("runTime").equals(currentProcess.get("completed")) && timeCount <= 100) {
				index++;
				pIndex = index % processList.size();
				currentProcess = processList.get(pIndex);
			}
			
			int currentCompleted = currentProcess.get("completed").intValue();
			currentCompleted++;
			currentProcess.put("completed", currentCompleted);
			for (int i = 0; i < processList.size(); i++) {
				if (processList.get(i).get("pid").equals(currentProcess.get("pid"))) {
					processList.set(i, currentProcess);
				}
			}
			
			System.out.print(timeCount + "\t");
			System.out.print("pid: " + currentProcess.get("pid") + "\n");
			result[timeCount] = currentProcess.get("pid").intValue();
			index++;
		}
		result[101] = processList.size();
		return result;
	}
	
	/**
	 * Simulates the non-preemptive highest priority algorithm
	 * @autohr jiangcun chilie
	 * @return array describes time table of the algorithm
	 */
	public static int[] NHPF()
	{
		
		ArrayList<HashMap<String, Number>> Priority1 = new ArrayList<HashMap<String, Number>>();
		ArrayList<HashMap<String, Number>> Priority2 = new ArrayList<HashMap<String, Number>>();
		ArrayList<HashMap<String, Number>> Priority3 = new ArrayList<HashMap<String, Number>>();
		ArrayList<HashMap<String, Number>> Priority4 = new ArrayList<HashMap<String, Number>>();
		
		List<HashMap<String, Number>> processList = processGenerator();
		printList(processList);
		int totalProcess = processList.size();
		int[] result = new int[102];
		int time = 0;
		
		for (int k=0; k<processList.size() ; k++){
		int Priority = processList.get(k).get("priority").intValue();
	    int  Rtime = processList.get(k).get("runTime").intValue();
	
		if (Priority==1){
			Priority1.add(processList.get(k));}
		if (Priority==2){
			Priority2.add(processList.get(k));}
		if (Priority==3){
			Priority3.add(processList.get(k));}
		if (Priority==4){
			Priority4.add(processList.get(k));}}
		
		
		for (int i=0;i<Priority1.size();i++)
		{     
		      int runT = Priority1.get(i).get("runTime").intValue();
		      for(int j=0;j<runT;j++) {
		    	  System.out.print((time)+"\t");
		    	  System.out.print("pid:"+Priority1.get(i).get("pid").intValue()+"\t\n");
		    	  result[time++] = Priority1.get(i).get("pid").intValue();
		      }
		  
	    }
		for (int i=0;i<Priority2.size();i++)
		{
			  int runT = Priority2.get(i).get("runTime").intValue();
			  for(int j=0;j<runT;j++){
			  System.out.print((time)+"\t");
	          System.out.print("pid:"+Priority2.get(i).get("pid").intValue()+"\t\n");
	          result[time++] = Priority2.get(i).get("pid").intValue();}
	    }
		for (int i=0;i<Priority3.size();i++)
		{
			  int runT = Priority3.get(i).get("runTime").intValue();
			  for(int j=0;j<runT;j++){
			  System.out.print((time)+"\t");
	          System.out.print("pid:"+Priority3.get(i).get("pid").intValue()+"\t\n");
	          result[time++] = Priority3.get(i).get("pid").intValue();}
			  
	    }
		for (int i=0;i<Priority4.size();i++)
		{
			  int runT = Priority4.get(i).get("runTime").intValue();
			  for(int j=0;j<runT;j++){
		      System.out.print((time)+"\t");
	          System.out.print("pid:"+Priority4.get(i).get("pid").intValue()+"\t\n");
	          result[time++] = Priority4.get(i).get("pid").intValue();}
	    }
		result[101] = totalProcess;
		return result;
	}
	
	/**
	 * Simulates the preemptive highest priority first algorithm
	 * @autohr jerry wu
	 * @return array describes time table of the algorithm
	 */
	protected static int[] PHPF() {
		List<HashMap<String, Number>> processList = processGenerator();
		printList(processList);
		Stack<HashMap<String, Number>> suspendStack = new Stack<HashMap<String, Number>>();
		HashMap<String, Number> currentProcess = null;
		int[] result = new int[102];
		result[101] = processList.size();
		
		for (int timeCount = 0; timeCount <= 100; timeCount++) {
			for (int i = 0; i < processList.size(); i++) {
				if (processList.get(i).get("arrivalTime").floatValue() <= timeCount && processList.get(i).get("completed").intValue() == 0) {
					if (currentProcess == null) {
						if (!(suspendStack.empty())) {
							currentProcess = suspendStack.pop();
							HashMap<String, Number> nextProcess = processList.get(i);
							float currentTurnAroundTime = (float) currentProcess.get("arrivalTime").floatValue() + currentProcess.get("runTime").floatValue();
							float nextTurnAroundTime = (float) nextProcess.get("arrivalTime").floatValue() + nextProcess.get("runTime").floatValue();
							int currentPriority = currentProcess.get("priority").intValue();
							int nextPriority = nextProcess.get("priority").intValue();
							if (currentPriority > nextPriority) {
								suspendStack.push(currentProcess);
								currentProcess = nextProcess;
							}
						} else {
							currentProcess = processList.get(i);
						}
					} else {
						HashMap<String, Number> nextProcess = processList.get(i);
						float currentTurnAroundTime = (float) currentProcess.get("arrivalTime").floatValue() + currentProcess.get("runTime").floatValue();
						float nextTurnAroundTime = (float) nextProcess.get("arrivalTime").floatValue() + nextProcess.get("runTime").floatValue();
						int currentPriority = currentProcess.get("priority").intValue();
						int nextPriority = nextProcess.get("priority").intValue();
						if (currentPriority > nextPriority) {
							suspendStack.push(currentProcess);
							currentProcess = nextProcess;
						}
					}
					break;
				}
				
				if (currentProcess == null) {
					if (!(suspendStack.empty())) {
						currentProcess = suspendStack.pop();
						break;
					}
				}
			}
			
			int currentCompleted = currentProcess.get("completed").intValue();
			currentCompleted++;
			currentProcess.put("completed", currentCompleted);
			for (int i = 0; i < processList.size(); i++) {
				if (processList.get(i).get("pid").equals(currentProcess.get("pid"))) {
					processList.set(i, currentProcess);
				}
			}
			
			System.out.print(timeCount + "\t");
			System.out.print("pid: " + currentProcess.get("pid") + "\t");
			result[timeCount] = currentProcess.get("pid").intValue();
			System.out.println();
			
			
			if (currentProcess.get("runTime").equals(currentProcess.get("completed"))) {
				currentProcess = null;
			}
		}
		
		return result;
		
	}
	
	/**
	 * Generate processes to fill 100 time slices, each process contains properties as process id, arrival time, run time, priority, and completed
	 * @return a list contains all processes
	 */
	private static List<HashMap<String, Number>> processGenerator() {
		List<HashMap<String, Number>> processList = new ArrayList<HashMap<String, Number>>();
		int pid = 1;
		while (isFilled(processList)) {
			HashMap<String, Number> p = new HashMap<String, Number>();
			int runTime = (int) (Math.random() * 10) + 1;
			int priority = 1 + (int) (Math.random() * 4);
			if (pid == 1) {
				p.put("arrivalTime", 0);
				p.put("runTime", runTime);
				p.put("pid", pid++);
				p.put("completed", 0);
				p.put("priority", priority);
			} else {
				float previousArrivalTime = processList.get(pid-2).get("arrivalTime").floatValue();
				int previousRunTime = processList.get(pid-2).get("runTime").intValue();
				float arrivalTime = (float) (previousArrivalTime + (Math.random() * (float) previousRunTime));
				p.put("arrivalTime", arrivalTime);
				p.put("runTime", runTime);
				p.put("pid", pid++);
				p.put("completed", 0);
				p.put("priority", priority);
			}
			processList.add(p);
		}
		int runTimeSum = 0;
		for (int i = 0; i < processList.size(); i++) {
			runTimeSum += processList.get(i).get("runTime").intValue();
		}
		int runTime = 100 - runTimeSum + 1;
		int priority = 1 + (int) (Math.random() * 4);
		HashMap<String, Number> p = new HashMap<String, Number>();
		float previousArrivalTime = processList.get(pid-2).get("arrivalTime").floatValue();
		int previousRunTime = processList.get(pid-2).get("runTime").intValue();
		float arrivalTime = (float) (previousArrivalTime + (Math.random() * (float) previousRunTime));
		p.put("arrivalTime", arrivalTime);
		p.put("runTime", runTime);
		p.put("pid", pid);
		p.put("completed", 0);
		p.put("priority", priority);
		processList.add(p);
		return processList;
	}
	
	private static boolean isFilled(List<HashMap<String, Number>> pList) {
		int runTimeSum = 0;
		for (int i = 0; i < pList.size(); i++) {
			runTimeSum += pList.get(i).get("runTime").intValue();
		}
		if (runTimeSum >= 90) return false;
		return true;
	}
	
	private static void printList(List<HashMap<String, Number>> pl) {
		for (int i = 0; i < pl.size(); i++) {
			System.out.print("pid: "+pl.get(i).get("pid")+"\t");
			System.out.print("Arrival Time: "+pl.get(i).get("arrivalTime")+"\t");
			System.out.print("Run Time: "+pl.get(i).get("runTime")+"\t");
			System.out.println("Priority: "+pl.get(i).get("priority"));
		}
		System.out.println();
	}
	
	/**
	 * Calculate the average turn around time for non preemptive algorithms
	 * @param ary time table to be calculated
	 * @return average turn around time
	 */
	private static float getATT1(int[] ary) {
		float result = 0;
		int totalProcess = ary[101];
		int tProcess = 0;
		for (int i = 0; i <= 100; i++) {
			if (i == 0) {
				tProcess = ary[i];
			} else if (tProcess != ary[i]) {
				tProcess = ary[i];
				result += i;
			}
		}
		result = result + 101;
		result = result / totalProcess;
		return result;
	}
	
	/**
	 * Calculate the average waiting time and response time for non preemptive algorithms
	 * @param ary time table to be calculated
	 * @return average waiting time/response time
	 */
	private static float getAWT1(int[] ary) {
		float result = 0;
		int totalProcess = ary[101];
		int tProcess = 0;
		for (int i = 0; i <= 100; i++) {
			if (i == 0) {
				tProcess = ary[i];
			} else if (tProcess != ary[i]) {
				tProcess = ary[i];
				result += i;
			}
		}
		result = result / totalProcess;
		return result;
	}
	
	/**
	 * Calculate the average turn around time for preemptive algorithms
	 * @param ary time table to be calculated
	 * @return average turn around time
	 */
	private static float getATT2(int[] ary) {
		float result = 0;
		int totalProcess = ary[101];
		int[] tAry = new int[101];
		int[] resultAry = new int[totalProcess];
		for (int i = 0; i <= 100; i++) {
			tAry[i] = ary[i];
		}
		
		for (int i = 1; i <= totalProcess; i++) {
			for (int j = 100; j >= 0; j--) {
				if (tAry[j] == i) {
					resultAry[i-1] = j + 1;
					break;
				}
			}
		}
		for (int i = 0; i < totalProcess; i++) {
			result += resultAry[i];
		}
		result = result / totalProcess;
		return result;
	}
	
	/**
	 * Calculate the average response time for preemptive algorithms
	 * @param ary time table to calculate
	 * @return average response time
	 */
	private static float getART2(int[] ary) {
		float result = 0;
		int totalProcess = ary[101];
		int[] tAry = new int[101];
		int[] resultAry = new int[totalProcess];
		for (int i = 0; i <= 100; i++) {
			tAry[i] = ary[i];
		}
		
		for (int i = 1; i <= totalProcess; i++) {
			for (int j = 0; j <= 100; j++) {
				if (tAry[j] == i) {
					resultAry[i-1] = j;
					break;
				}
			}
		}
		
		for (int i = 0; i < totalProcess; i++) {
			result += resultAry[i];
		}
		result = result / totalProcess;
		return result;
	}
	
	/**
	 * Calculate the average waiting time for preemptive algorithms
	 * @param ary time table to be calculated
	 * @return average waiting time
	 */
	private static float getAWT2(int[] ary) {
		float result = 0;
		int totalProcess = ary[101];
		int[] tAry = new int[101];
		for (int i = 0; i <= 100; i++) {
			tAry[i] = ary[i];
		}
		
		int[] startPositions = new int[totalProcess];
		int[] endPositions = new int[totalProcess];
		int[] resultAry = new int[totalProcess];
		
		for (int i = 1; i <= totalProcess; i++) {
			for (int j = 0; j <= 100; j++) {
				if (tAry[j] == i) {
					startPositions[i-1] = j;
					break;
				}
			}
		}
		
		for (int i = 1; i <= totalProcess; i++) {
			for (int j = 100; j >= 0; j--) {
				if (tAry[j] == i) {
					endPositions[i-1] = j + 1;
					break;
				}
			}
		}
		
		for (int i = 1; i <= totalProcess; i++) {
			int count = 0;
			for (int j = 0; j < endPositions[i-1]; j++) {
				if (tAry[j] != i) {
					count++;
				}
			}
			resultAry[i-1] = count;
		}
		
		for (int i = 0; i < totalProcess; i++) {
			result += resultAry[i];
		}
		result = result / totalProcess;
		
		return result;
	}
	
	private static float getAverage(float[] ary) {
        float result = 0; 
        for (int i = 0; i < ary.length; i++) {
                result += ary[i];
        }
        result = result / ary.length;
        return result;
	}
}
